const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const PENDING = 'pending'
class MyPromise {
  constructor(execute) {
    this.state = PENDING
    this.fulfillList =[]
    this.rejectList =[]

/*
* 注意这里的方法是定义在构造方法中的，当然定义在外面也没事
* 这里的方法是箭头函数 之所以写成箭头函数的话可以保证不管外面怎么调用this都是静态的 class中的方法最好定义为静态的
* */
   let resolve =value =>{

      if (this.state === PENDING){
        this.state = FULFILLED
      }
      this.value = value

      this.fulfillList.forEach(fn =>{
        fn()
      })
    }

  let reject =reason =>{
      if (this.state === PENDING){
        this.state = REJECTED
      }
      this.reason = reason
      this.rejectList.forEach(fn =>{
        fn(this.reason)
      })
    }

    try {
      execute(resolve,reject);
    } catch (e) {
     reject(e)
    }

  }


  then(onResolve,onReject){
    let promise2 = new _Promise((resolve1, reject1) => {
      if (this.state === FULFILLED){
        // typeof  onResolve === 'function' && onResolve(this.value)
        /*
        * 这里加定时器的是因为then内部的代码是异步执行的，其次如果这里不加定时器的话promise2会是未定义
        * */
        setTimeout(()=>{
          if (typeof  onResolve === 'function'){
            let x = onResolve(this.value)
            this.resolvePromise(promise2, x, resolve1, reject1)
          }
        })

      }else if (this.state === REJECTED){
        setTimeout(()=>{
          // typeof  onReject === 'function' && onReject(this.reason)
          if (typeof  onReject === 'function'){
            let x = onReject(this.reason)
            this.resolvePromise(promise2, x, resolve1, reject1)
          }
        })

      }else{
        // this.fulfillList.push(onResolve)
        // this.rejectList.push(onReject)

        /*
        * 注意这里的定时器是加在push里面而不是在push外面加定时器
        * 如果在push外面加的话也就意外着这行代码没有实际的执行，也就是并没有把函数放到队列
        * 这时候如果resolve/reject执行了会在队列内找不到回调函数使用
        *
        * */
          this.fulfillList.push(()=>{
            setTimeout(()=>{
            let x = onResolve(this.value)
            this.resolvePromise(promise2, x, resolve1, reject1)
          })

          this.rejectList.push(()=>{
            let x = onReject(this.reason)
            this.resolvePromise(promise2, x, resolve1, reject1)
          })
        })
      }
    })
    return promise2

  }

   resolvePromise(promise2, x, resolve, reject){

  }
}